#include "date.h"

#define is_leap(y)				((y)%100?((y)%4?0:1):((y)%400?0:1))

static unsigned short year_days(unsigned short year)
{
	return is_leap(year)?366:365;
}

static unsigned char month_days(unsigned short year, unsigned char month)
{
	switch (month)
	{
	case 1: case 3: case 5: case 7: case 8: case 10: case 12:
	return 31;
	case 4: case 6: case 9: case 11:
	return 30;
	case 2:
	return is_leap(year)?29:28;
	default:
	return 0;
	}
}

int set_date(date *date, unsigned short year, unsigned char month, unsigned char day)
{
	unsigned int count = 0;
	unsigned short y = 1900;
	unsigned char m = 1;
	
	if (year < 1900 || month > 12 || day > month_days(year, month)) return 0;
	for (y = 1900; y < year; y++) count = count + year_days(y);
	for (m = 1; m < month; m++) count = count + month_days(year, m);
	count += day;
	
	date->count = count;
	date->year = year;
	date->month = month;
	date->day = day;

	return 1;
}

int update_date(date *date, int offset)
{
	unsigned int count = date->count + offset;
	unsigned short y = 1900;
	unsigned char m = 1;
	
	if (count < 0) return 0;
	while (count > year_days(y)) count = count - year_days(y++);
	while (count > month_days(y, m)) count = count - month_days(y, m++);

	date->year = y;
	date->month = m;
	date->day = count;
	date->count += offset;

	return 1;
}
